package com.bot.service.rag;

import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.Metadata;
import dev.langchain4j.data.document.loader.FileSystemDocumentLoader;
import dev.langchain4j.data.document.splitter.DocumentByParagraphSplitter;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.rag.content.retriever.ContentRetriever;
import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.FileCopyUtils;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

/**
 * 初始化rag知识库  生成响应的bean
 */
@Configuration
public class RagConfig {
    @Resource   //注入向量模型
    private EmbeddingModel qwenEmbeddingModel;

    @Resource   //注入向量存储模型
    private EmbeddingStore<TextSegment> embeddingStore;
    @Bean
    public ContentRetriever contentRetriever(){
        //实现rag
        //加载文档
        Document document;
        try {
            // 尝试使用文件系统路径（开发环境）
            File file = new File("src/main/resources/docs/如何交到朋友 - 实用建议指南.md");
            if (file.exists()) {
                document = FileSystemDocumentLoader.loadDocument(file.getAbsolutePath());
            } else {
                // ⭐如果文件系统路径不存在，尝试从classpath加载（打包后的jar环境）
                // 从classpath读取文件内容而不是获取文件路径
                ClassPathResource resource = new ClassPathResource("docs/如何交到朋友 - 实用建议指南.md");
                String content = FileCopyUtils.copyToString(
                    new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8));
                // 创建文档对象，使用Metadata类型
                Metadata metadata = Metadata.from("file_name", resource.getFilename());
                document = Document.from(content, metadata);
            }
        } catch (IOException e) {
            // 如果从classpath加载也失败，提供更友好的错误信息
            throw new RuntimeException("无法加载文档：" + e.getMessage() + 
                "，请确保资源文件存在于正确的位置（src/main/resources/docs/目录下）。", e);
        }
        //文档切割  按照分段切割  最大100个字符 每次最多重叠50个字符
        DocumentByParagraphSplitter documentByParagraphSplitter = new DocumentByParagraphSplitter(100, 50);
        //⭐自定义文档加载器 把文档转化成向量并且保存
        EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
                .documentSplitter(documentByParagraphSplitter)  //文档加载器
                //为每个切割后的文档碎片添加名称
                .textSegmentTransformer(textSegment -> {
                    return TextSegment.from(textSegment.metadata().getString("file_name") +  //文档加载器自动补充的元信息
                            "\n" + textSegment.text(), textSegment.metadata());
                })
                //指定向量模型
                .embeddingModel(qwenEmbeddingModel)
                .embeddingStore(embeddingStore)
                .build();
        //加载文档
        ingestor.ingest(document);

        //⭐自定义内容加载器
        EmbeddingStoreContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder()
                .embeddingStore(embeddingStore)
                .embeddingModel(qwenEmbeddingModel)
                .maxResults(5)  //指定最多返回的结果
                .minScore(0.75)  // 最低分数   过滤分数小于0.75的内容
                .build();
        return contentRetriever;
    }
}
